package com.ylc.chat.JUI;

import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import com.ylc.chat.client.ClientDataBuffer;
import com.ylc.chat.client.ClientUtil;
import com.ylc.chat.common.Request;
import com.ylc.chat.common.Response;
import com.ylc.chat.common.ResponseStatus;
import com.ylc.chat.entity.Chatrecord;
import com.ylc.chat.entity.User;
import com.ylc.chat.service.ChatrecordService;
import com.ylc.chat.service.FriendsService;
import com.ylc.chat.service.UserService;
import com.ylc.chat.util.TransfromUtil;

/**
 * @Author: ylc
 * @Description:聊天界面
 */
public class ChatFrame extends JFrame {
    private JPanel contentPane;
    // 聊天标题
    private JLabel myfriendLabel_1;
    // 在线好友显示框
    public static JScrollPane onlinePane;
    // 离线好友显示框
    public static JScrollPane offlinePane;
    // 接收消息记录显示
    public static JScrollPane receiveRecordArea;
    // 接收记录
    private List<Chatrecord> receiveRecordList;
    // 发送消息记录显示
    public static JScrollPane sendRecordArea;
    // 发送记录
    private List<Chatrecord> sendRecordList;
    // 输入窗口
    private JTextArea inputTextArea;
    private static UserService userService = new UserService();
    private static FriendsService friendsService = new FriendsService();
    private static ChatrecordService chatrecordService = new ChatrecordService();

    // 对方用户
    private static String goalUserName = "";
    // 好友列表<uname,uid>
    private static final Map<String, Integer> friendsMap = new HashMap<>();

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
//					ChatFrame frame = new ChatFrame();
//					frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public ChatFrame() {
        this.init();
        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        this.setVisible(true);
    }

    public void init() {
        setTitle("欢迎用户" + ClientDataBuffer.currentUser.getUname());
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 1000, 700);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        contentPane = new JPanel();
        contentPane.setBackground(new Color(192, 192, 192));
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));

        setContentPane(contentPane);
        contentPane.setLayout(null);

        JPanel panel = new JPanel();
        panel.setBounds(0, 0, 257, 663);
        contentPane.add(panel);
        panel.setLayout(null);

        JButton btnNewButton_1 = new JButton("+添加好友");
        btnNewButton_1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
            }
        });
        btnNewButton_1.setBounds(74, 618, 97, 23);
        panel.add(btnNewButton_1);

        JLabel myfriendLabel = new JLabel("在线好友列表");
        myfriendLabel.setFont(new Font("宋体", Font.BOLD, 14));
        myfriendLabel.setBounds(77, 10, 105, 31);
        panel.add(myfriendLabel);

        JLabel myfriendLabel_2 = new JLabel("离线好友列表");
        myfriendLabel_2.setFont(new Font("宋体", Font.BOLD, 14));
        myfriendLabel_2.setBounds(69, 312, 105, 31);
        panel.add(myfriendLabel_2);

        // 在线好友显示框
        onlinePane = new JScrollPane();
        onlinePane.setBounds(34, 47, 180, 255);
        panel.add(onlinePane);
        // 离线好友显示框
        offlinePane = new JScrollPane();
        offlinePane.setBounds(34, 353, 180, 255);
        panel.add(offlinePane);


        // 在线好友列表
        loadData();
        JList onlineUsersList = new JList(TransfromUtil.formatStringArr(ClientDataBuffer.onlineUsers));
        onlinePane.setViewportView(onlineUsersList);
        onlineUsersList.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        // 离线好友列表
        JList offUsersList = new JList(TransfromUtil.formatStringArr(ClientDataBuffer.offUsers));
        offlinePane.setViewportView(offUsersList);
        offUsersList.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);


        // 列表项监听
        onlineUsersList.addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                if (!e.getValueIsAdjusting()) {
                    // 获取当前选中好友的姓名
                    String curName = (String) onlineUsersList.getSelectedValue();
                    goalUserName = curName;
                    selectFriend();
                }
            }
        });
        offUsersList.addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                if (!e.getValueIsAdjusting()) {
                    // 获取当前选中好友的姓名
                    String curName = (String) offUsersList.getSelectedValue();
                    goalUserName = curName;
                    selectFriend();
                }
            }
        });

        JPanel panel_2 = new JPanel();
        panel_2.setBounds(267, 0, 718, 481);
        contentPane.add(panel_2);
        panel_2.setLayout(null);

        myfriendLabel_1 = new JLabel("群聊");
        myfriendLabel_1.setHorizontalAlignment(SwingConstants.CENTER);
        myfriendLabel_1.setFont(new Font("宋体", Font.BOLD, 14));
        myfriendLabel_1.setBounds(10, 10, 708, 31);
        panel_2.add(myfriendLabel_1);

        // 接收消息窗口（左）
        receiveRecordArea = new JScrollPane();
        receiveRecordArea.setBounds(10, 51, 348, 420);
        panel_2.add(receiveRecordArea);
        // 发送消息窗口（右）
        sendRecordArea = new JScrollPane();
        sendRecordArea.setBounds(356, 51, 360, 420);
        panel_2.add(sendRecordArea);

        JPanel panel_3 = new JPanel();
        panel_3.setBounds(267, 504, 718, 116);
        contentPane.add(panel_3);
        panel_3.setLayout(null);

        inputTextArea = new JTextArea();
        inputTextArea.setBounds(0, 0, 718, 116);
        panel_3.add(inputTextArea);

        JButton btnNewButton = new JButton("发送");
        btnNewButton.setToolTipText("按Enter键发送消息");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                // 按钮点击发送
                sendTxtMsg();
            }
        });
        // 回车发送数据
        inputTextArea.addKeyListener(new KeyAdapter(){
            public void keyPressed(KeyEvent e){
                if(e.getKeyCode() == Event.ENTER){
                    sendTxtMsg();
                }
            }
        });
        btnNewButton.setBounds(757, 630, 97, 23);
        contentPane.add(btnNewButton);

        JButton btnNewButton_2 = new JButton("关闭");
        btnNewButton_2.setToolTipText("退出整个程序");
        btnNewButton_2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                logout();
            }
        });
        btnNewButton_2.setBounds(888, 630, 97, 23);
        contentPane.add(btnNewButton_2);

        // 关闭窗口
        this.addWindowListener(new WindowAdapter(){
            public void windowClosing(WindowEvent e) {
                logout();
            }
        });
    }


    /**
     * 获取好友列表,并为客户端启动一个监听线程，持续接收服务端的响应信息
     */
    public void loadData() {
        Request req = new Request();
        req.setAction("getFriends");
        req.setAttribute("uid",ClientDataBuffer.currentUser.getUid());
        //获取响应
        Response response = null;
        try {
            response = ClientUtil.sendTextRequest(req);
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        if(response.getStatus() == ResponseStatus.OK){
            Object obj = response.getData("friends");
            // 将object存储到list中
            List<User> onlineList = new ArrayList<>();
            List<User> offList = new ArrayList<>();
            if (obj instanceof ArrayList<?>) {
                for (Object o : (List<?>) obj) {
                    User curUser = User.class.cast(o);
                    if(curUser.getOnline() == 1){
                        // 在线
                        onlineList.add(curUser);
                        friendsMap.put(curUser.getUname(),curUser.getUid());
                    }else{
                        // 离线
                        offList.add(curUser);
                    }
                }
            }
            ClientDataBuffer.onlineUsers = onlineList;
            ClientDataBuffer.offUsers = offList;
        }else{
            JOptionPane.showMessageDialog(null,"服务器错误！");
        }

    }



    // 选择好友事件
    public void selectFriend() {

        // 修改聊天窗口标题
        myfriendLabel_1.setText(goalUserName);

        // 显示对应好友聊天记录
        Integer receiveUid = friendsMap.get(goalUserName);

        // 发送目标用户id
        Request req = new Request();
        req.setAction("getRecord");
        req.setAttribute("receiveUid",receiveUid);
        //获取响应
        Response response = null;
        try {
            response = ClientUtil.sendTextRequest(req);
        } catch (IOException e1) {
            e1.printStackTrace();
        }


        // 获取与当前好友的所有聊天记录
        Object sendObj = response.getData("sendRecord");
        sendRecordList = new ArrayList<>();
        Object receiveObj = response.getData("receiveRecord");
        receiveRecordList = new ArrayList<>();

        // Object ==> List<Chatrecord>
        if (sendObj instanceof ArrayList<?>) {
            for (Object o : (List<?>) sendObj) {
                Chatrecord chatrecord = Chatrecord.class.cast(o);
                sendRecordList.add(chatrecord);
            }
        }
        if (receiveObj instanceof ArrayList<?>) {
            for (Object o : (List<?>) receiveObj) {
                Chatrecord chatrecord = Chatrecord.class.cast(o);
                receiveRecordList.add(chatrecord);
            }
        }
        // List<Chatrecord>格式化为字符串
        String[] sendRecord = format(sendRecordList);
        String[] receiveRecord = format(receiveRecordList);

        // 回显到界面
        JList send = new JList(sendRecord);
        sendRecordArea.setViewportView(send);

        JList receive = new JList(receiveRecord);
        receiveRecordArea.setViewportView(receive);
    }
    // 关闭客户端
    private void logout() {
        int select = JOptionPane.showConfirmDialog(ChatFrame.this,
                "确定退出吗？\n\n退出程序将中断与服务器的连接!", "退出聊天室",
                JOptionPane.YES_NO_OPTION);
        if (select == JOptionPane.YES_OPTION) {
            Request req = new Request();
            req.setAction("exit");
            req.setAttribute("user", ClientDataBuffer.currentUser);

            try {
                ClientUtil.sendTextRequest(req);
            } catch (IOException ex) {
                ex.printStackTrace();
            }finally{
                System.exit(0);
            }
        }else{
            this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        }
    }
    // 发送数据
    private void sendTxtMsg(){
        // 获取输入数据
        String text = inputTextArea.getText();
        // 清空当前聊天框
        inputTextArea.setText(null);
        // 向服务器发送聊天数据
        Request req = new Request();
        Chatrecord chatrecord = new Chatrecord(text, new Date(), ClientDataBuffer.currentUser.getUid(), friendsMap.get(goalUserName), Chatrecord.TEXTTYPE);
        req.setAction("sendRecord");
        req.setAttribute("chatrecord",chatrecord);

        //获取响应
        Response response = null;
        try {
            response = ClientUtil.sendTextRequest(req);
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        if(response.getStatus() == ResponseStatus.OK) {
            // 发送记录界面显示聊天记录
            sendRecordList.add(chatrecord);
            String[] sendRecord = format(sendRecordList);
            JList send = new JList(sendRecord);
            sendRecordArea.setViewportView(send);
        }

    }

    // 包装消息记录展示样式
    private String[] format(List<Chatrecord> recordList){
        String[] record = new String[recordList.size()];
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for(int i = 0; i < record.length; i++){
            Chatrecord curRecord = recordList.get(i);
            record[i] = ClientDataBuffer.currentUser.getUname() + " " + sf.format(curRecord.getDate()) + " " + curRecord.getRecord();
        }
        return record;
    }
}
